<script lang="ts" setup name="ManageDesign">
import { provide, reactive, ref } from 'vue'
import useUserStore from '@g/store/modules/user'
import AddForm from './form-design/AddForm.vue'
import AddList from './form-design/AddList.vue'
import AddProject from './project-design/AddProject.vue'
import CreateFunStep from './function-design/CreateFunStep.vue'
import ShowPreview from './ShowPreview.vue'
import './design.scss'
import ModelListDesign from './ModelListDesign.vue'
import type { dataSources, typeListData } from './interface'
import {
  getFormId,
  getFunById,
  getInterfaces,
  getModuleField,
  getModulePreview,
  getProjectPreview,
  getType
} from '@/MainApp/apis/manage-design'
import headForm from '@/assets/images/head_form.svg'
import headFun from '@/assets/images/head_fun.svg'
import headProject from '@/assets/images/head_project.svg'
import { systemConfig } from '@/system.config'

const formData = reactive({
  name: '',
  scaffoldType: '',
  createName: ''
})
provide('formData', formData)
const typeList = ref<Array<typeListData>>([])
const addFormdialogVisible = ref(false)
const projectVisible = ref(false)
const funVisible = ref(false)
const projectData = ref<any>(null)
const modelListDesignRef = ref()
const addListdialogVisible = ref<any>(false)
const showPreviewVisible = ref<any>(false)
const editData = ref<any>(null)
const serverFields = ref<any>(null)
const interfacesForm = ref<any>(null)
const groupInterfaces = ref<any>(null)
const createVisible = ref<any>(false)
provide('projectData', projectData)
const listData = ref<any>(null)
const previewData = ref<any>(null)
const createData = [
  {
    src: headProject,
    id: 'first',
    activeName: 'first',
    label: '工程模式',
    desc: '适用于项目开发初期，未在本地创建服务时使用，可追加功能、表单和列表定义。'
  },
  {
    src: headFun,
    id: 'second',
    activeName: 'second',
    label: '功能模式',
    desc: '适用于本地已创建服务，但业务功能未开发时使用，可追加表单和列表定义。'
  },
  {
    src: headForm,
    id: 'third',
    activeName: 'third',
    label: '表单模式',
    desc: '独立表单工具，用于表单创建和配置。'
  }
].filter(item =>
  systemConfig.manageDesign?.designMode.includes(item.label as any)
)

let currentActive = createData[0]?.id || 'first'
const activeVal = ref(currentActive)

const handleSearch = async () => {
  currentActive = activeVal.value
  modelListDesignRef.value?.setActiveName(currentActive)
  projectVisible.value = false
  funVisible.value = false
  addFormdialogVisible.value = false
  addListdialogVisible.value = false
  editData.value = null
  listData.value = null
  // await modelListDesignRef.value.handleClick()
}

const handleAddProject = async (data: any) => {
  projectVisible.value = false
  await handleSearch()
  projectData.value = data
  if (data.goFun)
    funVisible.value = true
}
const handCreateOpen = () => {
  createVisible.value = true
}
const handCreateClose = () => {
  createVisible.value = false
}

const handleCreate = (activeName: string) => {
  activeVal.value = activeName
  switch (activeName) {
    case 'first':
      projectVisible.value = true
      break
    case 'second':
      funVisible.value = true
      break
    case 'third':
      addFormdialogVisible.value = true
      break
    default:
      break
  }
}
const ceratClick = (data: any) => {
  createVisible.value = false
  currentActive = data.activeName
  handleCreate(data.activeName)
}
const getTypeList = async () => {
  const { success, data } = await getType()
  if (success)
    typeList.value = data
}
getTypeList()

const addfun = (data: any) => {
  projectData.value = { ...data, projectId: data.id, goFun: 'fun', from: 'fun' }
  funVisible.value = true
}
const generateId = () => {
  return Math.floor(
    Math.random() * 100000 + Math.random() * 20000 + Math.random() * 5000
  )
}
const queryInterfaces = async (id: any, str: string) => {
  let formId = ''
  if (!str) {
    const { success, data } = await getFormId()
    if (success)
      formId = data
  }
  if (str === 'edit')
    formId = editData.value?.id

  const res1 = await getInterfaces(id).then(res => {
    if (res.success) {
      if (res.data) {
        const list: any = []
        groupInterfaces.value = res.data.map((item: any) => {
          let interData: dataSources = {
            common: item.common,
            dataSourceId: `ds${generateId()}`,
            uniqueName: item.uniqueName,
            requestURL: `DSV['apiHost']+'${item.address}'`,
            requestMethod: item.requestMethod,
            description: '',
            headers: [],
            params: '{}',
            type: item.type,
            data: JSON.stringify({
              page: 1,
              formId,
              queryDetailDTOList: [],
              rows: 10
            }),
            configHandlerCode: '  return config',
            dataHandlerCode: '  return result.data.data;',
            errorHandlerCode: '  $message.error(error.message);',
            dataSetEnabled: false,
            dataSets: []
          }
          if (item.type === 'PAGE' && item.common) {
            interData = {
              ...interData,
              headers: [
                {
                  name: 'Authorization',
                  type: 'String',
                  value: useUserStore().token
                }
              ],
              data: JSON.stringify({
                page: 1,
                formId,
                queryDetailDTOList: [],
                rows: 10
              }),
              dataHandlerCode: `result.data.data = result.data.data.map((item)=>{
  return {
    ...item,
    ...JSON.parse(item.formDataJson)
  }
})
return result.data.data;`
            }
            list.push(interData)
          }
          if (item.type !== 'PAGE' && item.common) {
            interData = {
              ...interData,
              headers: [
                {
                  name: 'Authorization',
                  type: 'String',
                  value: useUserStore().token
                }
              ],
              data: JSON.stringify({ formId })
            }
            list.push(interData)
          }
          return interData
        })
        interfacesForm.value = {
          widgetList: [],
          formConfig: {
            modelName: 'formData',
            refName: 'vForm',
            rulesName: 'rules',
            labelWidth: 80,
            labelPosition: 'left',
            size: '',
            labelAlign: 'label-left-align',
            cssCode: '',
            customClass: '',
            functions: '',
            layoutType: 'PC',
            jsonVersion: 3,
            dataSources: list,
            onFormCreated: '',
            onFormMounted: '',
            onFormDataChange: ''
          }
        }
      }
    }
  })
  return res1
}
const queryField = async (id: any) => {
  const res = await getModuleField(id)
  if (res.success)
    serverFields.value = res.data?.children || []

  return res
}
const addForm = async (row: any) => {
  await Promise.all([
    await queryField(row.id),
    await queryInterfaces(row.id, '')
  ]).then(() => {
    if (row.changeFormType === 'form')
      addFormdialogVisible.value = true
    else addListdialogVisible.value = true

    listData.value = { ...row }
  })
}

const handleUpdateFun = (flag: any) => {
  funVisible.value = flag
  editData.value = null
  projectData.value = null
}
const handleUpdateForm = () => {
  serverFields.value = null
  addFormdialogVisible.value = false
  interfacesForm.value = null
  editData.value = null
  listData.value = null
}
const handleUpdateList = (flag: any) => {
  addListdialogVisible.value = flag
  editData.value = null
  listData.value = null
}
const handleUpdateProject = (flag: any) => {
  projectVisible.value = flag
  editData.value = null
}
const handleUpdatePreview = (flag: any) => {
  showPreviewVisible.value = flag
  previewData.value = null
  editData.value = null
}

const editChange = async (row: any) => {
  editData.value = row
  if (row.scaffoldType === 'PROJECT')
    projectVisible.value = true

  if (row.scaffoldType === 'PAGE' || row.scaffoldType === 'FORM') {
    Promise.all([
      await queryField(row.moduleId),
      await queryInterfaces(row.moduleId, 'edit')
    ]).then(() => {
      addFormdialogVisible.value = true
    })
  }

  if (row.scaffoldType === 'LIST') {
    await Promise.all([
      await queryField(row.moduleId),
      await queryInterfaces(row.moduleId, '')
    ]).then(() => {
      addListdialogVisible.value = true
    })
  }

  if (row.scaffoldType === 'MODULE') {
    const { data, success } = await getFunById(row.id)
    if (success) {
      editData.value = { ...data }
      funVisible.value = true
    }
    else {
      editData.value = null
    }
  }
}
const handlePreview = async (row: any) => {
  editData.value = row
  if (row.scaffoldType === 'MODULE') {
    const { data, success } = await getModulePreview(row.id)
    if (success) {
      previewData.value = data
      showPreviewVisible.value = true
    }
  }
  if (row.scaffoldType === 'PROJECT') {
    const { data, success } = await getProjectPreview(row.id)
    if (success) {
      previewData.value = data
      showPreviewVisible.value = true
    }
  }
}
const handleTabClick = (val: any) => {
  activeVal.value = val
  modelListDesignRef.value?.setActiveName(val)
}

const dialogWidth = computed(
  () => (createData.length - 1 >= 0 ? createData.length - 1 : 0) * 225 + 350
)
</script>

<template>
  <IkPageMain fixed>
    <IkPageTabs
      v-model="activeVal"
      :tabs="createData"
      @tab-click="handleSearch"
    >
      <ModelListDesign
        ref="modelListDesignRef"
        :active="activeVal"
        @handleTabClick="handleTabClick"
        @handleCreate="handCreateOpen"
        @addFun="addfun"
        @addForm="addForm"
        @edit="editChange"
        @preview="handlePreview"
      />
    </IkPageTabs>
    <AddForm
      :active-val="activeVal"
      :visible="addFormdialogVisible"
      :edit-data="editData"
      :list-data="listData"
      :server-fields="serverFields"
      :interfaces-form="interfacesForm"
      :group-interfaces="groupInterfaces"
      @confirm="handleSearch"
      @update:visible="handleUpdateForm"
      @cancel="handleUpdateForm"
    />
    <AddList
      :edit-data="editData"
      :list-data="listData"
      :visible="addListdialogVisible"
      :server-fields="serverFields"
      @confirm="handleSearch"
      @update:visible="handleUpdateList"
      @cancel="handleUpdateList"
    />
    <CreateFunStep
      :visible="funVisible"
      :edit-data="editData"
      @confirm="handleSearch"
      @update:visible="handleUpdateFun"
      @cancel="handleUpdateFun"
    />
    <AddProject
      :visible="projectVisible"
      :edit-data="editData"
      @change-data="handleSearch"
      @confirm="handleAddProject"
      @update:visible="handleUpdateProject"
      @cancel="handleUpdateProject"
    />
    <ShowPreview
      :visible="showPreviewVisible"
      :preview-data="previewData"
      :edit-data="editData"
      @confirm="handleUpdatePreview"
      @update:visible="handleUpdatePreview"
      @cancel="handleUpdatePreview"
    />
    <el-dialog
      v-model="createVisible"
      title="新建"
      draggable
      :width="dialogWidth"
      align-center
      :close-on-click-modal="false"
      @closed="handCreateClose"
      @open="handCreateOpen"
    >
      <div class="create-cen">
        <div
          v-for="(item, index) in createData"
          :key="index"
          class="w-create"
          @click="ceratClick(item)"
        >
          <img :src="item.src">
          <h1>{{ item.label }}</h1>
          <span>{{ item.desc }}</span>
        </div>
      </div>
    </el-dialog>
  </IkPageMain>
</template>

<style scoped lang="scss">
.model-tabs {
  background: var(--el-bg-color);
  padding: 15px;
}

.manager-cen {
  position: relative;

  .manager-btn {
    position: absolute;
    top: 20px;
    right: 15px;
    z-index: 100;
  }
}

.create-cen {
  display: flex;
  align-items: center;
  justify-content: space-around;

  .w-create {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-direction: column;
    box-sizing: border-box;
    border: 1px solid var(--ik-border-color);
    border-radius: 5px;
    font-size: 16px;
    font-weight: 400;
    line-height: 28px;
    width: 240px;
    height: 300px;
    margin: 5px;
    padding: 10px;
    cursor: pointer;
    transition: color 0.25s, background-color 0.25s;

    &:hover {
      background-color: var(--ik-theme-color-re);
      color: var(--ik-text-hover-color);
    }

    span {
      font-size: 12px;
    }
  }
}
</style>
